<?php

namespace app\admin\controller;

use app\admin\model\Order as ModelOrder;
use app\common\controller\Backend;
use think\facade\Filesystem;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;

/**
 * 订单
 */
class Order extends Backend
{
    /**
     * Order模型对象
     * @var object
     * @phpstan-var \app\admin\model\Order
     */
    protected object $model;

    protected array|string $preExcludeFields = ['id'];

    protected string|array $quickSearchField = ['id'];

    public function initialize(): void
    {
        parent::initialize();
        $this->model = new \app\admin\model\Order();
    }


    /**
     * 若需重写查看、编辑、删除等方法，请复制 @see \app\admin\library\traits\Backend 中对应的方法至此进行重写
     */


    public function importOrder()
    {
        $filePath = request()->param('file');
        // 添加public目录的基础路径
        $fullPath = public_path() . ltrim($filePath, '/\\');

        if (!file_exists($fullPath)) {
            $this->error('文件不存在');
        }

        // 验证文件类型
        $ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION));
        if (!in_array($ext, ['xlsx', 'xls'])) {
            $this->error('请上传Excel文件');
        }


        // 读取Excel文件
        $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($ext == 'xlsx' ? 'Xlsx' : 'Xls');
        $spreadsheet = $reader->load($fullPath);
        $sheet = $spreadsheet->getActiveSheet();

        // 字段映射
        $fieldsMap = [
            '订单编号' => 'order_no',
            '物流名称' => 'wul_name',
            '物流单号' => 'wul_no',
            '物流状态' => 'wul_status',
            '物流时间' => 'wul_time',
            '收货名称' => 'shouh_name',
            '收货电话' => 'shouh_phone',
            '收货地址' => 'shouh_address',
            '订单状态' => 'order_status',
            '退款时间' => 'end_tuik_time',
            '商品名称' => 'goods_name',
            '商品规格' => 'goods_sku',
            '商品单价' => 'goods_price',
            '商品数量' => 'num',
            '优惠金额' => 'youh_price',
            '发货时间' => 'cn_fah_time',
            '下单时间' => 'xiad_time',
            '付款时间' => 'fuk_time',
            '成交时间' => 'chengj_time'
        ];

        // 获取总行数
        $highestRow = $sheet->getHighestRow();
        // 获取总列数
        $highestColumn = $sheet->getHighestColumn();
        $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);

        // 验证表头
        $header = [];
        for ($col = 1; $col <= $highestColumnIndex; $col++) {
            $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col);
            $header[] = $sheet->getCell($columnLetter . '1')->getValue();
        }

        // if (count(array_diff($header, array_keys($fieldsMap))) > 0) {
        //     $this->error('Excel表头格式不正确');
        // }

        // 读取数据
        $data = [];
        for ($row = 2; $row <= $highestRow; $row++) {
            $rowData = [];
            for ($col = 1; $col <= $highestColumnIndex; $col++) {
                $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col);
                $value = $sheet->getCell($columnLetter . $row)->getValue();
                $excelField = $header[$col - 1];
                if (isset($fieldsMap[$excelField])) {
                    $dbField = $fieldsMap[$excelField];
                    
                    // 判断是否为Excel日期格式并转换
                    $value = $this->convertExcelDate($value, $dbField);
                    
                    $rowData[$dbField] = $value;
                }
            }
            // var_dump($rowData);
            if (!empty($rowData) && $rowData['order_no']) {
                // 处理特殊字段
                // $rowData['wul_time'] = strtotime($rowData['wul_time']);
                // $rowData['end_tuik_time'] = $rowData['end_tuik_time'] ? strtotime($rowData['end_tuik_time']) : 0;
                $rowData['goods_price'] = floatval($rowData['goods_price']);
                $rowData['num'] = intval($rowData['num']);
                $rowData['youh_price'] = floatval($rowData['youh_price']);

                $data[] = $rowData;
            }
        }
        // var_dump($data);
        if (empty($data)) {
            $this->error('没有可导入的数据');
        }

        // 开启事务
        \think\facade\Db::startTrans();
        // try {
        foreach ($data as $item) {
            // 检查订单是否已存在
            $exists = $this->model->where('order_no', $item['order_no'])->find();
            if ($exists) {
                // 更新订单
                $this->model->where('order_no', $item['order_no'])->update($item);
            } else {
                // 新增订单
                $this->model->insert($item);
            }
        }
        \think\facade\Db::commit();
        $this->success('导入成功');
        // } catch (\Exception $e) {
        //     \think\facade\Db::rollback();
        //     $this->error('导入失败：' . $e->getMessage());
        // }


        // 删除临时文件
        @unlink($fullPath);
    }

    public function importImage()
    {
        $filePath = request()->param('file');
        // 添加public目录的基础路径
        $fullPath = public_path() . ltrim($filePath, '/\\');

        if (!file_exists($fullPath)) {
            $this->error('文件不存在');
        }

        // 验证文件类型
        $ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION));
        if ($ext !== 'zip') {
            $this->error('请上传ZIP压缩包');
        }

        // 获取zip文件所在目录
        $extractPath = dirname($fullPath) . '/' . pathinfo($fullPath, PATHINFO_FILENAME);

        // 如果目录已存在，先删除
        if (is_dir($extractPath)) {
            $this->delDir($extractPath);
        }

        // 创建解压目录
        mkdir($extractPath, 0777, true);

        // 创建ZipArchive对象
        $zip = new \ZipArchive();
        if ($zip->open($fullPath) !== true) {
            $this->error('无法打开ZIP文件');
        }

        // 解压文件
        $zip->extractTo($extractPath);
        $zip->close();

        // 递归获取所有文件
        $files = $this->getAllFiles($extractPath);

        foreach ($files as $file) {
            // 获取文件名（不含后缀）作为物流单号
            $wulNo = pathinfo($file, PATHINFO_FILENAME);

            // 获取相对于public目录的路径
            $relativePath = str_replace(public_path(), '', $file);
            $relativePath = ltrim($relativePath, '/\\');

            // 更新订单图片路径
            $this->model->where('wul_no', $wulNo)->update(['image' => '/' . $relativePath]);
        }

        // 删除原zip文件
        @unlink($fullPath);

        $this->success('图片导入成功');
    }

    /**
     * 递归获取目录下所有文件
     * @param string $dir
     * @return array
     */
    private function getAllFiles($dir)
    {
        $files = [];
        $handle = opendir($dir);

        if ($handle) {
            while (($file = readdir($handle)) !== false) {
                if ($file != '.' && $file != '..') {
                    $path = $dir . '/' . $file;
                    if (is_dir($path)) {
                        $files = array_merge($files, $this->getAllFiles($path));
                    } else {
                        $files[] = $path;
                    }
                }
            }
            closedir($handle);
        }

        return $files;
    }

    /**
     * 递归删除目录
     * @param string $dir
     * @return bool
     */
    private function delDir($dir)
    {
        if (!is_dir($dir)) {
            return false;
        }

        $handle = opendir($dir);
        while (($file = readdir($handle)) !== false) {
            if ($file != '.' && $file != '..') {
                $path = $dir . '/' . $file;
                if (is_dir($path)) {
                    $this->delDir($path);
                } else {
                    unlink($path);
                }
            }
        }
        closedir($handle);
        return rmdir($dir);
    }

    /**
     * 转换Excel日期格式
     * @param mixed $value 单元格值
     * @param string $fieldName 字段名
     * @return mixed 转换后的值
     */
    private function convertExcelDate($value, $fieldName)
    {
        // 定义需要转换日期的时间字段
        $dateFields = [
            'wul_time',      // 物流时间
            'end_tuik_time', // 退款时间
            'cn_fah_time',   // 发货时间
            'xiad_time',     // 下单时间
            'fuk_time',      // 付款时间
            'chengj_time'    // 成交时间
        ];
        
        // 如果不是时间字段，直接返回原值
        if (!in_array($fieldName, $dateFields)) {
            return $value;
        }
        
        // 如果值为空，返回空值
        if ($value === null || $value === '') {
            return $value;
        }
        
        // 判断是否为Excel日期格式（数字且大于1000，Excel日期从1900年开始）
        if (is_numeric($value) && $value > 1000) {
            // Excel日期从1900年1月1日开始计算天数
            // Excel日期基准：1900年1月1日
            $excelBaseDate = 25569; // 1970年1月1日对应的Excel日期值
            $unixTimestamp = ($value - $excelBaseDate) * 86400; // 转换为秒
            
            // 检查时间戳是否合理（在1970-2100年范围内）
            if ($unixTimestamp > 0 && $unixTimestamp < 4102444800) {
                return date('Y-m-d H:i:s', $unixTimestamp);
            }
        }
        
        // 如果不是Excel日期格式，尝试用strtotime转换
        if (is_string($value)) {
            $timestamp = strtotime($value);
            if ($timestamp !== false) {
                return date('Y-m-d H:i:s', $timestamp);
            }
        }
        
        // 如果都不行，返回原值
        return $value;
    }

    public function batchEdit()
    {
        $ids = $this->request->post('ids');
        $data = $this->request->post('data');

        if (empty($ids) || empty($data)) {
            $this->error('参数错误');
        }

        // 数据预处理
        if (isset($data['goods_price'])) {
            $data['goods_price'] = floatval($data['goods_price']);
        }
        if (isset($data['num'])) {
            $data['num'] = intval($data['num']);
        }
        if (isset($data['youh_price'])) {
            $data['youh_price'] = floatval($data['youh_price']);
        }

        // 开启事务
        \think\facade\Db::startTrans();



        $x = $this->model->whereIn('id', $ids)->update($data);
        \think\facade\Db::commit();
        $this->success('修改成功');

        \think\facade\Db::rollback();
    }
}
